﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Xml;
using Microsoft.SharePoint.WebControls;
using System.Reflection;
using System.Globalization;

namespace achappey.SharePoint.Livestamp
{
    public class LivestampField : SPFieldComputed
    {
        #region Constructors

         public LivestampField(SPFieldCollection fields, string fieldName)
           : base(fields, fieldName)
        { }

         public LivestampField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        { }

        #endregion

        #region Implementation of Get/Set InnerXmlForNode

         public void SetField(string fieldName)
         {
             SetInnerXmlForNode("FieldRefs", string.Format("<FieldRef Name='{0}' />",
                fieldName));

             DateTimeFormatInfo dateInfo = this.ParentList.ParentWeb.Locale.DateTimeFormat;

             SetInnerXmlForNode("DisplayPattern", string.Format(@"<HTML><![CDATA[<script src='/_layouts/achappey.SharePoint.Livestamp/jquery.js'></script>
                            <script src='/_layouts/achappey.SharePoint.Livestamp/moment.js'></script>
                            <script src='/_layouts/achappey.SharePoint.Livestamp/livestamp.js'></script>
                            <script src='/_layouts/achappey.SharePoint.Livestamp/date.js'></script>
                            <script src='/_layouts/achappey.SharePoint.Livestamp/SharePoint.Livestamp.js'></script>]]></HTML>
                            <HTML><![CDATA[<div><SCRIPT>formatField(']]></HTML> <Field Name='{0}' />
                            <HTML><![CDATA[', '{1}', '{2}');</SCRIPT></div>]]></HTML>",
                fieldName,
                dateInfo.ShortDatePattern,
                dateInfo.ShortTimePattern));
         }

         public string FieldName
         {
             get
             {
                 string xml = GetInnerXmlForNode("FieldRefs");

                 if (!string.IsNullOrEmpty(xml))
                 {
                     xml = xml.Substring(xml.IndexOf("Name=") + 6);
                     return xml.Substring(0, xml.IndexOf("/>") - 2);
                 }

                 return null;
             }
         }

        public void SetInnerXmlForNode(string nodeName, string innerXml)
        {
            Type fldType = this.GetType();

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(String.Format("<{0}>{1}</{0}>", nodeName, innerXml));
            
            MethodInfo miSetXml = fldType.GetMethod("SetInnerXmlForNode", BindingFlags.Instance | BindingFlags.NonPublic);
            miSetXml.Invoke(this, new object[] { nodeName, doc.DocumentElement.InnerXml });
        }

        public string GetInnerXmlForNode(string nodeName)
        {
            string result = null;

            Type fldType = this.GetType();
            MethodInfo miGetXml = fldType.GetMethod("GetNodeFromXmlDom", BindingFlags.Instance | BindingFlags.NonPublic);
            XmlNode resultNode = miGetXml.Invoke(this, new object[] { nodeName }) as XmlNode;

            if (resultNode != null)
            {
                StringBuilder sb = new StringBuilder();
                XmlWriterSettings settings = new XmlWriterSettings()
                    {
                        Indent = true,
                        ConformanceLevel = ConformanceLevel.Fragment
                    };

                using (XmlWriter writer = XmlTextWriter.Create(sb, settings))
                    resultNode.WriteContentTo(writer);
                
                result = sb.ToString();
            }

            return result;
        }

        
        
        public override BaseFieldControl FieldRenderingControl
        {
            get
            {
                BaseFieldControl fieldControl = new LivestampFieldControl(this);

                fieldControl.FieldName = InternalName;

                return fieldControl;
            }
        }

        #endregion    
    }
    
}
